package com.superbytecode.cloud.rocketmq.configure;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.superbytecode.cloud.rocketmq.consumer.provider.OpenMQConsumeProvider;
import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.messaging.converter.CompositeMessageConverter;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;

/**
 * All rights Reserved, Designed By www.super-master.com
 *
 * @ProjectName: beacon-cloud
 * @Package: com.superbytecode.cloud.rocketmq.configure
 * @ClassName: OpenMQConfiguration
 * @Description: []
 * <p> </p>
 * @Author: [Lance Ting]
 * @Date: 2024/11/1 22:34
 * @Version: V1.0
 * @Copyright: 2024 www.super-master.com Inc. All rights reserved.
 * TODO: 注意,本文件Lance Ting所作,如果转载或使用请标明具体出处!
 **/
@Configuration
@Import({OpenMQConsumeProvider.class, OpenMQConsumeProvider.class})
@ConditionalOnProperty(name = "rocketmq.server-provider", havingValue = "open_source", matchIfMissing = true)
public class OpenMQConfiguration {

    private final DateTimeFormatter FORMAT_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private final DateTimeFormatter FORMAT_DATETIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Bean
    public JavaTimeModule javaTimeModule() {
        // RocketMQ原始配置并不支持Java时间类型
        JavaTimeModule module = new JavaTimeModule();
        module.addDeserializer(LocalDate.class, new LocalDateDeserializer(FORMAT_DATE));
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(FORMAT_DATETIME));
        //
        module.addSerializer(LocalDate.class, new LocalDateSerializer(FORMAT_DATE));
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(FORMAT_DATETIME));
        return module;
    }

    /**
     * 覆盖原有的rocketmq 序列化
     * <p>解决RocketMQ Jackson不支持Java时间类型配置
     * {@link org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration}
     * </p>
     */
    @Bean
    @Primary
    public RocketMQMessageConverter rocketMQMessageConverter(JavaTimeModule module) {
        RocketMQMessageConverter rocketMessageConverter = new RocketMQMessageConverter();
        CompositeMessageConverter messageConverter = (CompositeMessageConverter) rocketMessageConverter.getMessageConverter();
        messageConverter.getConverters().stream()//
                .filter(mc -> Objects.equals(mc.getClass(), MappingJackson2MessageConverter.class))//
                .findAny().ifPresent(converter -> {
                    MappingJackson2MessageConverter jsonMessageConverter = (MappingJackson2MessageConverter) converter;
                    ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
                    objectMapper.registerModule(module);
                });
        return rocketMessageConverter;
    }
}